import { Inject, Provide } from '@midwayjs/core';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Between, Repository, MoreThanOrEqual } from 'typeorm';
import { OrderInfoEntity } from '../entity/info';
import { PluginService } from '../../plugin/service/info';
import { StudentStudentEntity } from '../../student/entity/student';
import { CouponUserEntity } from '../../coupon/entity/user';
import { ClassTrainLogEntity } from '../../class/entity/trainLog';
import { AppointmentInfoEntity } from '../../appointment/entity/info';

/**
 * 订单信息
 */
@Provide()
export class OrderInfoService extends BaseService {
  @InjectEntityModel(OrderInfoEntity)
  orderInfoEntity: Repository<OrderInfoEntity>;

  @InjectEntityModel(StudentStudentEntity)
  studentStudentEntity: Repository<StudentStudentEntity>;

  @InjectEntityModel(CouponUserEntity)
  couponUserEntity: Repository<CouponUserEntity>;

  @InjectEntityModel(ClassTrainLogEntity)
  classTrainLogEntity: Repository<ClassTrainLogEntity>;

  @InjectEntityModel(AppointmentInfoEntity)
  appointmentInfoEntity: Repository<AppointmentInfoEntity>;

  @Inject()
  pluginService: PluginService;

  @Inject()
  ctx;
  

  // 支付配置全局变量
  private readonly payConfig = {
    "北京双博视": {
      "key": "shbos20250421WechatPayDetailweix",
      "appid": "wx2d1366273b335654",
      "mchid": "1713344906",
      "publicKey": "http://shbos.com/cert/apiclient_cert.pem",
      "notify_url": "http://shbos.com/api/admin/order/info/payNotify",
      "privateKey": "http://shbos.com/cert/apiclient_key.pem",
      "verifyPublicKey": "http://shbos.com/cert/apiclient_cert.p12"
    },
    "燕郊店": {
      "key": "shbosyj20241105wechatPayCert0001",
      "appid": "wx2d1366273b335654",
      "mchid": "1698169384",
      "publicKey": "http://shbos.com/cert/yanjiao_1698169384_20250425_cert/apiclient_cert.pem",
      "notify_url": "http://shbos.com/api/admin/order/info/payNotifyYanjiao",
      "privateKey": "http://shbos.com/cert/yanjiao_1698169384_20250425_cert/apiclient_key.pem",
      "verifyPublicKey": "http://shbos.com/cert/yanjiao_1698169384_20250425_cert/apiclient_cert.p12"
    },
    "房山店": {
      "key": "shbosyj20241105wechatPayCert0002",
      "appid": "wx2d1366273b335654",
      "mchid": "1707345686",
      "publicKey": "http://shbos.com/cert/fangshan_1707345686_20250425_cert/apiclient_cert.pem",
      "notify_url": "http://shbos.com/api/admin/order/info/payNotifyFangshan",
      "privateKey": "http://shbos.com/cert/fangshan_1707345686_20250425_cert/apiclient_key.pem",
      "verifyPublicKey": "http://shbos.com/cert/fangshan_1707345686_20250425_cert/apiclient_cert.p12"
    },
    "上地店": {
      "key": "shbosyj20241105wechatPayCert0002",
      "appid": "wx2d1366273b335654",
      "mchid": "1707345686",
      "publicKey": "http://shbos.com/cert/fangshan_1707345686_20250425_cert/apiclient_cert.pem",
      "notify_url": "http://shbos.com/api/admin/order/info/payNotifyFangshan",
      "privateKey": "http://shbos.com/cert/fangshan_1707345686_20250425_cert/apiclient_key.pem",
      "verifyPublicKey": "http://shbos.com/cert/fangshan_1707345686_20250425_cert/apiclient_cert.p12"
    },
    "亦庄店": {
      "key": "shbosyj20241105wechatPayCert0003",
      "appid": "wx2d1366273b335654",
      "mchid": "1707547265",
      "publicKey": "http://shbos.com/cert/yizhuang_1707547265_20250425_cert/apiclient_cert.pem",
      "notify_url": "http://shbos.com/api/admin/order/info/payNotifyYizhuang",
      "privateKey": "http://shbos.com/cert/yizhuang_1707547265_20250425_cert/apiclient_key.pem",
      "verifyPublicKey": "http://shbos.com/cert/yizhuang_1707547265_20250425_cert/apiclient_cert.p12"
    }
  };

  
  /**
   * 分页方法重写过滤数据
   */
  async page(query, options) {
    const result = await super.page(query, options); // 先获取所有数据
    // 获取每个学员的最新预约信息
    for (const order of result.list) {
      // 拼写产品信息
      order.productName = order.productDetails.map(item => item.name).join('、') || '';
    }

    return result;
  }
  /**
   * 取消支付
   */
  async cancelPay(orderId: number) {
    const order = await this.orderInfoEntity.findOne({
      where: { id: orderId }
    });

    if (!order) {
      throw new CoolCommException('订单不存在');
    }

    if (order.status !== 0) {
      throw new CoolCommException('只能取消待支付的订单');
    }

    // 如果订单有使用优惠券，将优惠券状态改回未使用
    if (order.discountDetails) {
      let discountDetails;
      try {
        // 如果是字符串，则解析为JSON对象
        discountDetails = typeof order.discountDetails === 'string' 
          ? JSON.parse(order.discountDetails) 
          : order.discountDetails;

        if (Array.isArray(discountDetails)) {
          for (const detail of discountDetails) {
            if (detail && detail.type === 'coupon' && detail.userCouponId) {
              await this.couponUserEntity.update(
                { id: detail.userCouponId },
                { status: 0, updateTime: new Date() }
              );
            }
          }
        }
      } catch (error) {
        console.error('解析优惠信息失败:', error);
      }
    }

    console.log('order:', orderId, order.discountDetails);

    // 更新订单状态为已取消
    await this.orderInfoEntity.update(orderId, {
      status: 4,  // 已取消
      updateTime: new Date()
    });

    return {
      success: true,
      message: '订单取消成功'
    };
  }

  /**
   * 检查订单支付状态
   */
  async checkPayStatus(orderId: number) {
    const order = await this.orderInfoEntity.findOne({
      where: { id: orderId }
    });

    if (!order) {
      return {
        isPaid: false,
        message: '订单不存在'
      };
    }

    const statusMap = {
      0: '待支付',
      1: '已支付',
      2: '已发货',
      3: '已完成',
      4: '已取消'
    };

    return {
      isPaid: order.status === 1,  // 1表示已支付
      payStatus: order.status,
      statusText: statusMap[order.status] || '未知状态',
      message: order.status === 1 ? '支付成功' : statusMap[order.status]
    };
  }

  /**
   * 生成支付二维码
   */
  async payQrcode(orderId: number) {
    // 查询订单信息
    const order = await this.orderInfoEntity.findOne({
      where: { id: orderId }
    });

    if (!order) {
      throw new CoolCommException('订单不存在');
    }

    if (order.status !== 0) {
      throw new CoolCommException('订单状态不正确');
    }
    
    // 获得插件实例
    const plugin = await this.pluginService.getInstance('pay-wx');

    // 获得插件配置
    const config = await plugin['getConfig']();

    // 根据shopId获取对应的店铺配置
    let shopConfig = this.payConfig['北京双博视'];
    switch (order.shopId) {
      case 77:
        shopConfig = this.payConfig['燕郊店'];
        break;
      case 78:
        shopConfig = this.payConfig['房山店'];
        break;
      case 229:
        shopConfig = this.payConfig['上地店'];
        break;
      case 79:
        shopConfig = this.payConfig['亦庄店'];
        break;
      default:
        shopConfig = this.payConfig['北京双博视'];
        break;
    }

    console.log('shopConfig:', shopConfig);
    
    // 获得微信支付 SDK 实例
    const instance = await plugin['getInstance'](shopConfig);

    // 查询学生信息获取手机号
    const student = await this.studentStudentEntity.findOne({
      where: { id: order.userId }
    });

    // 计算支付金额
    let payAmount = Math.floor(order.payAmount * 100); // 默认转换为分
    
    // 测试账号特殊处理
    if (student && student.phone === '13317640150' || student.phone === '18600089105') {
      payAmount = 1; // 测试账号只需支付1分钱
    }

    // Native，返回的信息可以直接生成二维码，用户扫码支付
    const params = {
      description: `订单支付-${order.orderNumber}`,
      out_trade_no: order.orderNumber,
      notify_url: shopConfig.notify_url,
      amount: {
        total: payAmount,
        currency: 'CNY'
      },
      scene_info: {
        payer_client_ip: this.ctx.ip,
      },
    };

    const result = await instance.transactions_native(params);
    return {
      codeUrl: result.data.code_url,
      orderId: order.id,
      orderNumber: order.orderNumber
    };
  }

  /**
   * 处理微信支付回调
   */
  async handleWxPayNotify(body, shopId) {
    try {
      console.log('收到微信支付回调:', body, shopId);
      // 获得插件实例
      const plugin = await this.pluginService.getInstance('pay-wx');

      // 根据shopId获取对应的店铺配置
      let shopConfig = this.payConfig['北京双博视'];
      switch (shopId) {
        case 77:
          shopConfig = this.payConfig['燕郊店'];
          break;
        case 78:
          shopConfig = this.payConfig['房山店'];
          break;
        case 229:
          shopConfig = this.payConfig['上地店'];
          break;
        case 79:
          shopConfig = this.payConfig['亦庄店'];
          break;
        default:
          shopConfig = this.payConfig['北京双博视'];
          break;
      }

      // 获得微信支付 SDK 实例，传入对应店铺的配置
      const instance = await plugin['getInstance'](shopConfig);
      
      const { ciphertext, associated_data, nonce } = body.resource;
      const data: any = instance.decipher_gcm(ciphertext, associated_data, nonce);
      console.log('解密后的回调数据:', data);
      // 验签通过，处理业务逻辑
      if (data.trade_state == 'SUCCESS') {
          // 查询订单
          const order = await this.orderInfoEntity.findOne({
            where: { orderNumber: data.out_trade_no }
          });
          
          if (order) {
            // 更新订单状态
            await this.orderInfoEntity.update(order.id, {
              status: 1, // 已支付
              payStatus: 1,
              payTime: new Date(),
              transactionId: data.transaction_id,
              updateTime: new Date()
            });
            await this.paySuccess(order.id, 'wechatNotify');
          }
      }
      return 'success';
    } catch (error) {
      console.error('处理微信支付回调出错:', error);
      return 'fail';
    }
  }

  /**
   * 更新订单中使用的优惠券状态
   */
  private async updateCouponStatus(discountDetails: any) {
    if (!discountDetails || !discountDetails.length) {
      return;
    }

    for (const detail of discountDetails) {
      if (detail.type === 'coupon' && detail.couponId) {
        await this.couponUserEntity.update(
          { id: detail.userCouponId },
          { status: 1, updateTime: new Date() }
        );
      }
    }
  }

  /**
   * 重写add方法以支持优惠券状态更新
   */
  async add(param) {
    // 检查20天之内是否有预约，取最近的
    const appointment = await this.appointmentInfoEntity.findOne({
      where: {
        studentId: param.userId,
        comeType: 2,
        appointmentTime: MoreThanOrEqual(new Date(new Date().getTime() - 20 * 24 * 60 * 60 * 1000)),
        // orderId: 0,
      }
    });
    if (!appointment) {
      throw new CoolCommException('该学员20天之内没有完成就诊信息，无法开单');
    }
    // 检查订单商品
    if (!param.productDetails || 
        (typeof param.productDetails === 'string' && JSON.parse(param.productDetails).length === 0) ||
        (Array.isArray(param.productDetails) && param.productDetails.length === 0)) {
      throw new CoolCommException('请选择商品');
    }
    const result = await super.add(param);
    if (param.discountDetails) {
      await this.updateCouponStatus(param.discountDetails);
    }
    if (result && typeof result === 'object' && 'id' in result && typeof result.id === 'number') {
      await this.paySuccess(result.id);
    }
    return result;
  }

  /**
   * 订单支付完成后的处理
   */
  async paySuccess(orderId: number, type: string = 'add') {
    const order = await this.orderInfoEntity.findOne({
      where: { id: orderId }
    });
    if (!order) {
      throw new CoolCommException('订单不存在');
    }
    // 如果待支付下则不执行
    if (type === 'add' && order.payType === 0) {
      return;
    }
    // 查看订单商品中是否有训练次数，有则加到学员的训练次数中
    if (order.productDetails) {
      let productDetails;
      try {
        // 如果是字符串，则解析为JSON对象
        productDetails = typeof order.productDetails === 'string' 
          ? JSON.parse(order.productDetails) 
          : order.productDetails;

        if (Array.isArray(productDetails)) {
          let totalTrainCount = 0;
          let totalGiftCount = 0;

          // 遍历所有商品，累计训练次数和赠送次数
          for (const product of productDetails) {
            if (product.trainCount) {
              totalTrainCount += Number(product.trainCount) * Number(product.count);
            }
            if (product.giftCount) {
              totalGiftCount += Number(product.giftCount) * Number(product.count);
            }
          }

          // 如果有训练次数或赠送次数，则更新学员信息
          if (totalTrainCount > 0 || totalGiftCount > 0) {
            const student = await this.studentStudentEntity.findOne({
              where: { id: order.userId }
            });

            if (student) {
              // 更新学员的训练次数和赠送次数
              await this.studentStudentEntity.update(
                { id: order.userId },
                {
                  buyCount: (student.buyCount || 0) + totalTrainCount + totalGiftCount, 
                  remainCount: (student.remainCount || 0) + totalTrainCount + totalGiftCount,
                  trainCount: (student.trainCount || 0) + totalTrainCount,
                  giftCount: (student.giftCount || 0) + totalGiftCount,
                  updateTime: new Date()
                }
              );
              // 添加训练记录的更新日志
              await this.classTrainLogEntity.save({
                studentId: order.userId,  // 使用 studentId 而不是 userId
                count: totalTrainCount + totalGiftCount,
                trainCount: totalTrainCount,
                giftCount: totalGiftCount,
                operatorId: Number(order.sales),  // 确保 operatorId 是数字类型
                type: 0,  // 添加必要的类型字段
                time: new Date(),
                createTime: new Date(),
                updateTime: new Date()
              });
            }
          }
        }
      } catch (error) {
        console.error('解析商品详情失败:', error);
        throw new CoolCommException('处理商品详情失败');
      }
    }
    // 将最近的一条就诊预约信息登记上订单ID
    const lastAppoint = await this.appointmentInfoEntity.findOne({
      where: {
        studentId: order.userId,
        comeType: 2,
        orderId: 0,
      },
      order: {
        id: 'DESC'
      }
    });
    if (lastAppoint) {
      await this.appointmentInfoEntity.update(lastAppoint.id, {
        orderId: order.id,
      });
    }

    // 将当天的预约设置为签到
    const appoint = await this.appointmentInfoEntity.findOne({
      where: {
        studentId: order.userId,
        appointmentTime: Between(new Date(), new Date(new Date().setHours(23, 59, 59, 999)))
      }
    });
    if (appoint) {
      await this.appointmentInfoEntity.update(appoint.id, {
        appointmentStatus: 1,
        updateTime: new Date()
      });
    }
  }
}
